package com.byit.mail;

import com.sun.mail.util.MailSSLSocketFactory;
import org.aspectj.util.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.mail.*;
import javax.mail.internet.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.*;

/**
 * @ClassName SendMailService
 * @Description 发送邮件服务
 * @Author lxp
 * @Date 2018-12-29 11:17
 **/
@Service
public class SendMailService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JavaMailSender mailSender;

    //    @Value("${spring.mail.username}")
//    private String username;
    @Value("${spring.mail.account}")
    private String account;
    @Value("${spring.mail.pass}")
    private String pass;
    @Value("${spring.mail.host}")
    private String host;
    @Value("${spring.mail.port}")
    private String port;
    @Value("${spring.mail.protocol}")
    private String protocol;

    @Autowired
    private SpringTemplateEngine templateEngine;


    static class MyAuthenricator extends Authenticator {
        String u = null;
        String p = null;

        public MyAuthenricator(String u, String p) {
            this.u = u;
            this.p = p;
        }

        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(u, p);
        }
    }

//    @Autowired
//    private VelocityEngine velocityEngine;

    /**
     * 发送简单的邮件
     *
     * @param mapParam
     */
    public void sendSample(Map<String, String> mapParam) {


        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("919055887@qq.com");
        message.setTo("1360652124@qq.com");
        message.setSubject("主题：简单邮件");
        message.setText("测试邮件内容");

        mailSender.send(message);
    }


    /**
     * 发送简单的邮件
     *
     * @param mapParam
     */

    public void sendAttachmentsMail(Map<String, Object> mapParam) throws Exception {


        MimeMessage mimeMessage = mailSender.createMimeMessage();

        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setFrom("919055887@qq.com");
        helper.setTo("1360652124@qq.com");
        helper.setSubject("主题：有附件");
        helper.setText("有附件的邮件");
        MultipartFile file1 = (MultipartFile) mapParam.get("file");
        File f = null;
        try {
            f = File.createTempFile("tmp", null);
            file1.transferTo(f);
            f.deleteOnExit();     //使用完成删除文件
        } catch (IOException e) {
            e.printStackTrace();
        }

        FileSystemResource file = new FileSystemResource(f);
        helper.addAttachment("附件-1.jpg", file);
        helper.addAttachment("附件-2.jpg", file);

        mailSender.send(mimeMessage);
    }

    /**
     * 发送模板邮件
     *
     * @param message
     * @return
     */
    public boolean sendTemplate(MailMessage message) {
        //  message.setFrom(username);
        // TODO 参数校验...
        try {
            //构造消息
            MimeMessage mimeMessage = buildMimeMessage(message);
            //发送
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            logger.error("send mail error", e);
            return false;
        }
        return true;
    }

    private MimeMessage buildMimeMessage(MailMessage message) throws Exception {


//        Properties prop = new Properties();
//        //协议
//        prop.setProperty("mail.transport.protocol", protocol);
//        //服务器
//        prop.setProperty("mail.smtp.host", host);
//        //端口
//        prop.setProperty("mail.smtp.port", port);
//        //使用smtp身份验证
//        prop.setProperty("mail.smtp.auth", "true");
//        //使用SSL，企业邮箱必需！
//        //开启安全协议
//        MailSSLSocketFactory sf = null;
//        try {
//            sf = new MailSSLSocketFactory();
//            sf.setTrustAllHosts(true);
//        } catch (GeneralSecurityException e1) {
//            e1.printStackTrace();
//        }
//        prop.put("mail.smtp.ssl.enable", "true");
//        prop.put("mail.smtp.ssl.socketFactory", sf);
//
//        Session session = Session.getDefaultInstance(prop, new MyAuthenricator(account, pass));
//        session.setDebug(true);
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        //主题
        helper.setSubject(message.getSubject());
        //发送者
        helper.setFrom(message.getFrom());
        //接受者
        helper.setTo(message.getToList().toArray(new String[0]));
        //抄送
        if (!CollectionUtils.isEmpty(message.getCopyList())) {
            helper.setCc(message.getCopyList().toArray(new String[0]));
        }
        String attachementUtl = message.getParamMap().get("attachementUtl").toString();
        Map<String, Object> map = downLoadFromUrl(attachementUtl, null, "tmp");
        FileSystemResource attfile = new FileSystemResource((File) map.get("file"));
        helper.addAttachment((String) map.get("fileName"), attfile);
        Context context = new Context(Locale.CHINA);
        context.setVariables(message.getParamMap());
        //解析模版
        String content = templateEngine.process(message.getTemplateId(), context);
        helper.setText(content, true);
        return mimeMessage;

    }

    public void sendInlineMail() throws Exception {

        MimeMessage mimeMessage = mailSender.createMimeMessage();

        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setFrom("919055887@qq.com");
        helper.setTo("1360652124@qq.com");
        helper.setSubject("主题：嵌入静态资源");
        helper.setText("<html><body><img src=\"cid:weixin\" ></body></html>", true);

        FileSystemResource file = new FileSystemResource(new File("weixin.jpg"));
        helper.addInline("weixin", file);

        mailSender.send(mimeMessage);
    }

 /*   public void sendTemplateMail() throws Exception {

        MimeMessage mimeMessage = mailSender.createMimeMessage();

        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setFrom("919055887@qq.com");
        helper.setTo("1360652124@qq.com");
        helper.setSubject("主题：模板邮件");

        Map<String, Object> model = new HashedMap();
        model.put("username", "didi");
        String text = VelocityEngineUtils.mergeTemplateIntoString(
                velocityEngine, "template.html", "UTF-8", model);
        helper.setText(text, true);

        mailSender.send(mimeMessage);
    }*/


    public Map<String, Object> downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);

        //文件保存位置
        //  File saveDir = new File(savePath);
        // urlStr.substring(urlStr.lastIndexOf("."));
        String suffe = urlStr.substring(urlStr.lastIndexOf("."));
        String filename2 = urlStr.substring(urlStr.lastIndexOf("/") + 1);

        File tmp = File.createTempFile(savePath + File.separator + fileName, suffe);
        tmp.deleteOnExit();     //使用完成删除文件
        File file = new File(String.valueOf(tmp));
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if (fos != null) {
            fos.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }


        System.out.println("info:" + url + " download success");
        Map<String, Object> map = new HashMap();
        map.put("file", file);
        map.put("fileName", filename2);

        return map;
    }

    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     * 发送腾讯企业邮箱
     *
     * @param message
     * @return
     */
    public boolean send(MailMessage message) {
        Properties prop = new Properties();
        //协议
        prop.setProperty("mail.transport.protocol", protocol);
        //服务器
        prop.setProperty("mail.smtp.host", host);
        //端口
        prop.setProperty("mail.smtp.port", port);
        //使用smtp身份验证
        prop.setProperty("mail.smtp.auth", "true");
        //使用SSL，企业邮箱必需！
        //开启安全协议
        MailSSLSocketFactory sf = null;
        try {
            sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
        } catch (GeneralSecurityException e1) {
            e1.printStackTrace();
        }
        prop.put("mail.smtp.ssl.enable", "true");
        prop.put("mail.smtp.ssl.socketFactory", sf);

        Session session = Session.getDefaultInstance(prop, new MyAuthenricator(account, pass));
        session.setDebug(true);
        MimeMessage mimeMessage = new MimeMessage(session);
        try {
            //发件人
            mimeMessage.setFrom(new InternetAddress(account));        //可以设置发件人的别名
            //mimeMessage.setFrom(new InternetAddress(account));    //如果不需要就省略
            //收件人
           // mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(message.getToList().get(0)));
            //主题
            mimeMessage.setSubject(message.getSubject());
            //时间
            mimeMessage.setSentDate(new Date());
            //容器类，可以包含多个MimeBodyPart对象
            Multipart mp = new MimeMultipart();

            //MimeBodyPart可以包装文本，图片，附件
            MimeBodyPart body = new MimeBodyPart();
            //HTML正文
            Context context = new Context(Locale.CHINA);
            context.setVariables(message.getParamMap());
            //解析模版
            String content = templateEngine.process(message.getTemplateId(), context);
            body.setContent(content, "text/html; charset=UTF-8");
            mp.addBodyPart(body);

            //添加图片&附件
            body = new MimeBodyPart();
            Object objUtl1 = message.getParamMap().get("attachementUtl");
            //有附件
            if ( null!=objUtl1) {
                String attachementUtl =objUtl1.toString();
                Map<String, Object> map = downLoadFromUrl(attachementUtl, null, "tmp");
                body.attachFile((File) map.get("file"));
                mp.addBodyPart(body);
                body.setFileName(MimeUtility.encodeText(map.get("fileName").toString()));
            }


            //设置邮件内容
            mimeMessage.setContent(mp);
            //仅仅发送文本
            //mimeMessage.setText(content);
            mimeMessage.saveChanges();
            //多人邮件发送
            message.getToList().forEach(toAddr->{

                try {
                    mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddr));
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
                try {
                    Transport.send(mimeMessage);
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
